package saxion.speelveld.spaceengineer.controller;

import java.util.ArrayList;
import java.util.Random;

import saxion.speelveld.spaceengineer.R;
import saxion.speelveld.spaceengineer.buildings.SpaceCenter;
import saxion.speelveld.spaceengineer.model.Building;
import saxion.speelveld.spaceengineer.model.Difficulties;
import saxion.speelveld.spaceengineer.model.Game;
import saxion.speelveld.spaceengineer.model.ObstacleTile;
import saxion.speelveld.spaceengineer.model.Resource;
import saxion.speelveld.spaceengineer.model.ResourceTile;
import saxion.speelveld.spaceengineer.model.ResourceType;
import saxion.speelveld.spaceengineer.model.Tile;
import saxion.speelveld.spaceengineer.model.TradePlanet;

public class newGameCreator
{
	static Random random = new Random();

	/**
	 * 
	 * @param difficultie
	 *            Difficultie of the map
	 * @param sideSize
	 *            The lenght of each side of the map in Tiles
	 * @return The random generated map
	 */
	public static Tile[][] genMap(Difficulties difficultie, int sideSize)
	{
		Tile[][] map = new Tile[sideSize][sideSize];
		int typPlanet;

		// Planeet type bepalen, kan alleen als we meerdere sets hebben
		typPlanet = 1;

		// Elke Tile een achtergrond geven
		int r;
		for (int x = 0; x < sideSize; x++)
		{
			for (int y = 0; y < sideSize; y++)
			{
				// r = random.nextInt(10);
				map[x][y] = new Tile(0);
			}
		}

		// hoeveelheid resources en obstakels bepalen
		int howmanyresources = 16;
		int howmanyobstacles = 32;

		switch (difficultie)
		{
		case HARD:
			while (howmanyresources < 90)
				howmanyresources = random.nextInt(170);
			while (howmanyobstacles < 750)
				howmanyobstacles = random.nextInt(1000);
			break;
		case INSANE:
			while (howmanyresources < 80)
				howmanyresources = random.nextInt(160);
			while (howmanyobstacles < 1000)
				howmanyobstacles = random.nextInt(1500);
			break;
		case NORMAL:
			while (howmanyresources < 110)
				howmanyresources = random.nextInt(130);
			while (howmanyobstacles < 500)
				howmanyobstacles = random.nextInt(750);
			break;
		case EASY:
			while (howmanyresources < 120)
				howmanyresources = random.nextInt(150);
			while (howmanyobstacles < 250)
				howmanyobstacles = random.nextInt(500);
			break;
		default:
			System.out.println("niet verhandelde type");
			break;
		}

		ArrayList<Integer> res = new ArrayList<Integer>();
		boolean placed;

		// plaatsen van resource tiles
		for (int i = 0; i <= howmanyresources; i++)
		{
			placed = false;
			while (!placed)
			{
				int x = random.nextInt(sideSize);
				int y = random.nextInt(sideSize);
				while (x >= 48 && x <= 51 && y >= 48 && y <= 51)
				{
					x = random.nextInt(sideSize);
					y = random.nextInt(sideSize);
				}
				// TODO bepalen welke resource moet worden toegevoegd
				if (map[x][y].getClass().equals(Tile.class))
				{
					int rand = random.nextInt(10);
					if (rand == 1 || rand == 2)
					{
						map[x][y] = new ResourceTile(map[x][y].getBackgroundID(), ResourceType.GOLDORE);
						placed = true;
					}
					else if (rand > 2 && rand < 6)
					{
						map[x][y] = new ResourceTile(map[x][y].getBackgroundID(), ResourceType.IRONORE);
						placed = true;
					}
					else
					{
						map[x][y] = new ResourceTile(map[x][y].getBackgroundID(), ResourceType.SAND);
						placed = true;
					}

				}
			}
		}

		// random plaatsen van obstakels
		for (int i = 0; i <= howmanyobstacles; i++)
		{
			placed = false;
			while (!placed)
			{
				int x = random.nextInt(sideSize);
				int y = random.nextInt(sideSize);
				while (x >= 48 && x <= 51 && y >= 48 && y <= 51)
				{
					x = random.nextInt(sideSize);
					y = random.nextInt(sideSize);
				}
				// TODO bepalen welke resource moet worden toegevoegd
				if (map[x][y].getClass().equals(Tile.class))
				{
					int rand = random.nextInt(2);
					if (rand == 1)
					{
						map[x][y] = new ObstacleTile(map[x][y].getBackgroundID(), R.drawable.cratergroundlavafull3);
					}
					else
					{
						map[x][y] = new ObstacleTile(map[x][y].getBackgroundID(), R.drawable.groundtilewithrock);
					}
					placed = true;
				}
			}
		}

		return map;
	}

	public static int randomize(int i)
	{
		int cost = 0;
		int min = (int) (i - i * 0.05);
		int max = (int) (i + i * 0.05);
		while (cost < min)
		{
			cost = random.nextInt(max);
		}
		return cost;
	}

	public static int getResourceCost(ResourceType type)
	{
		int cost = -1;
		switch (type)
		{
		case CLOTHING:
			cost = randomize(500);
			break;
		case COTTON:
			cost = randomize(500);
			break;
		case FOOD:
			cost = randomize(500);
			break;
		case FURNITURE:
			cost = randomize(500);
			break;
		case GLASS:
			cost = randomize(500);
			break;
		case GOLD:
			cost = randomize(500);
			break;
		case GOLDORE:
			cost = randomize(500);
			break;
		case IRON:
			cost = randomize(500);
			break;
		case IRONORE:
			cost = randomize(500);
			break;
		case METAL:
			cost = randomize(500);
			break;
		case OXYGEN:
			cost = randomize(500);
			break;
		case SAND:
			cost = randomize(500);
			break;
		case WATER:
			cost = randomize(500);
			break;
		case WOOD:
			cost = randomize(500);
			break;
		default:
			cost = -1;
			break;

		}
		return cost;
	}

	private static String planetNameGen(int minChars, int maxChars)
	{
		String retString = "";
		char[] possibleCharacters = new char[] { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'
			, 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7',
			'8', '9', '0' };

		if (maxChars > minChars)
		{
			int amountOfCharacters = 0;

			while (amountOfCharacters < minChars)
			{
				amountOfCharacters = random.nextInt(maxChars);
			}

			for (int i = 0; i < maxChars; i++)
			{
				int randomChar = random.nextInt(possibleCharacters.length - 1);
				retString = retString + possibleCharacters[randomChar];
			}

		}
		return retString;
	}

	private static int genRandomPlanetImage()
	{
		int retImage = 0;
		int[] arrayOfImages = new int[] { R.drawable.planet001, R.drawable.planet002, R.drawable.planet003,
			R.drawable.planet004, R.drawable.planet005, R.drawable.planet006, R.drawable.planet007,
			R.drawable.planet008, R.drawable.planet009, R.drawable.planet010, R.drawable.planet011,
			R.drawable.planet012, R.drawable.planet013 };

		int randomImage = random.nextInt(arrayOfImages.length - 1);

		retImage = arrayOfImages[randomImage];

		return retImage;
	}

	public static ArrayList<TradePlanet> genTradePlanets(Difficulties difficultie)
	{
		ArrayList<TradePlanet> planets = new ArrayList<TradePlanet>();
		String[] names = { "Boro", "Baxalt", "B1XX32", "ZALT", "Elysia", "Zebes", "Tallon IV", "SR388", "Ceris",
			"Eris", "Iego", "Asion", "Bogden", "Cato Neimoida", "Nemata", "Acheron", "Erebus", "Yangtze", "Strabo",
			"Hekate", "Ploitari", "Kalabsha", "Kairavamori" };
		int amountOfPlanets = 0;
		switch (difficultie)
		{
		case HARD:
			amountOfPlanets = 10;
			break;
		case INSANE:
			amountOfPlanets = 8;
			break;
		case NORMAL:
			amountOfPlanets = 12;
			break;
		case EASY:
			amountOfPlanets = 14;
			break;
		default:
			System.out.println("niet verhandelde type");
			break;
		}

		for (int i = 0; i <= amountOfPlanets; i++)
		{
			TradePlanet planet = new TradePlanet(names[random.nextInt(names.length)]);

			int deals = random.nextInt(4);

			for (int b = 0; b <= deals; b++)
			{
				ResourceType type = ResourceType.values()[random.nextInt(ResourceType.values().length)];
				int cost = getResourceCost(type);

				while (cost == -1)
				{
					type = ResourceType.values()[random.nextInt(ResourceType.values().length)];
					cost = getResourceCost(type);
				}
				planet.AddtradeDeal(type, 200, cost);
			}

			planet.setPlanetImage(genRandomPlanetImage());

			planets.add(planet);

		}
		return planets;
	}

	/**
	 * returns a new Game.
	 * 
	 * @param difficultie
	 *            difficultie of the new game
	 * @param sideSize
	 *            the lenght of each side of the map in Tile
	 * @return
	 */
	public static Game GenGame(Difficulties difficultie, int sideSize)
	{
		Resource[] resources = new Resource[ResourceType.values().length];
		for (ResourceType RT : ResourceType.values())
		{
			resources[RT.ordinal()] = new Resource(RT, 1000);
		}

		resources[ResourceType.HAPPINESS.ordinal()].setAmount(40);
		resources[ResourceType.SCIENCEPOINTS.ordinal()].setAmount(25);
		// resources[ResourceType.ELECTRICITY.ordinal()].setAmount(300);
		// resources[ResourceType.WATER.ordinal()].setAmount(259);
		resources[ResourceType.MONEY.ordinal()].setAmount(6034);
		resources[ResourceType.STORAGESPACE.ordinal()].setAmount(9999);
		// resources[ResourceType.METAL.ordinal()].setAmount(600);
		ArrayList<TradePlanet> planets = genTradePlanets(difficultie);
		Game g = new Game(genMap(difficultie, sideSize), new ArrayList<Building>(), 0, difficultie, resources,
			planets.toArray(new TradePlanet[planets.size()]));
		g.setQueuedBuilding(new SpaceCenter());
		g.AddBuilding(49, 49, true, true);

		g.setViewCursor(45, 45);

		return g;
	}
}
